'''
Created on 20/set/2015

@author: Daniel
'''
from PyQt4                              import QtGui
from constants import constants
from Main.widgets.askForm    import AskFormEdit
import os
import logging
import sys
import datetime
import win32gui
import win32con
import win32api
import win32ui
import fnmatch
import traceback
import Image
import win32com.client
from os.path import expanduser
from win32com.client import Dispatch
import ImageMath
from constants.constants import ICON_MAIN
from constants.constants import TABLE_NAME_CONFIGURATIONS
#C:\Users\Daniel\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup

TRY_ICON_OBJ = None
    
def launchTryIconMessage(title, message, level='info'):
    if level.upper() == 'INFO':
        iconMode = 1 # Info
    elif level.upper() == 'WARNING':
        iconMode = 2    # No warning
    elif level.upper() == 'ERROR':
        iconMode = 3    # No critical
    else:
        iconMode = 0    # No icon
    TRY_ICON_OBJ.showMessage(title, message, iconMode)
    
def startUpEnable(pathFrom, startUpflag=False):
    '''
        C:\Users\Daniel\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\MineSweeper.exe
    '''
    try:
        if not pathFrom:
            return
        objShell = win32com.client.Dispatch("WScript.Shell")
        userMenu = objShell.SpecialFolders("StartMenu")
        pathTo = os.path.join(userMenu,'Programs\Startup',os.path.basename(str(pathFrom)))
        filename, file_extension = os.path.splitext(pathTo)
        file_extension = file_extension
        linkPath = filename+'.lnk'
        if startUpflag:
            osName = getOS()
            if osName == 'WINDOWS':
                shell = Dispatch('WScript.Shell')
                shortcut = shell.CreateShortCut(linkPath)
                shortcut.Targetpath = pathFrom
                shortcut.WorkingDirectory = os.path.dirname(pathFrom)
                shortcut.IconLocation = pathFrom
                shortcut.save()
            elif osName == 'LINUX':
                pass
                # To try on linuxs
                #os.symlink(pathFrom, pathTo)
        else:
            if os.path.exists(linkPath):
                os.remove(linkPath)
    except Exception, ex:
        logging.error(ex)

def getBaseVolumeName():
    volumePath = expanduser("~").split(':')[0]+':\\' 
    logging.debug('[getBaseVolumeName] volumePath: %s' %(volumePath))
    return volumePath
    
def getExeList():
    exeList = []
    if getOS() == 'WINDOWS':
        exeList = getExeFromPath(os.path.join(getBaseVolumeName(), 'Program Files'))
        exeList = exeList + getExeFromPath(os.path.join(getBaseVolumeName(), 'Program Files (x86)'))
    logging.info('[getExeList] exeList: %s' % (exeList))
    return exeList

def getProgramFiles():
    exeList = []
    if getOS() == 'WINDOWS':
        exeList = getExeFromPath(os.path.join(getBaseVolumeName(), 'Program Files'))
    logging.info('[getProgramFiles] exeList: %s' % (exeList))
    return exeList
    
def getProgramFiles86():
    exeList = []
    if getOS() == 'WINDOWS':
        exeList = getExeFromPath(os.path.join(getBaseVolumeName(), 'Program Files (x86)'))
    logging.info('[getProgramFiles86] exeList: %s' % (exeList))
    return exeList

def getPythonPathExe():
    exeList = []
    pythonExePath = sys.executable
    if os.path.exists(pythonExePath):
        pythonInstallDir = os.path.dirname(pythonExePath)
        exeList = getExeFromPath(pythonInstallDir)
    logging.info('[getPythonPathExe] exeList: %s' % (exeList))
    return exeList
        
def getExeFromPath(startingPath='', extension='.exe'):
    outExeList = []
    if os.path.exists(startingPath):
        for root, dirnames, filenames in os.walk(startingPath):
            dirnames
            for filename in fnmatch.filter(filenames, '*%s'%(extension)):
                outExeList.append(str(os.path.join(root,filename)))
    #logging.debug('[getExeFromPath] startingPath: %s, extension: %s \n outExeList: %s' %(startingPath, extension, outExeList))
    return outExeList

def distance2(a, b):
    return (a[0] - b[0]) * (a[0] - b[0]) + (a[1] - b[1]) * (a[1] - b[1]) + (a[2] - b[2]) * (a[2] - b[2])

def makeColorTransparent(image, color, thresh2=0):
    image = image.convert("RGBA")
    red, green, blue, alpha = image.split()
    image.putalpha(ImageMath.eval("""convert(((((t - d(c, (r, g, b))) >> 31) + 1) ^ 1) * a, 'L')""",
        t=thresh2, d=distance2, c=color, r=red, g=green, b=blue, a=alpha))
    return image

def getIconPathFromExe(exePath=''):
    try:
        #logging.debug('[getIconPathFromExe] exePath: %s' %(exePath))
        if os.path.exists(exePath):
            exePath = str(exePath)
            ico_x = win32api.GetSystemMetrics(win32con.SM_CXICON)
            ico_y = win32api.GetSystemMetrics(win32con.SM_CYICON)
            large, small = win32gui.ExtractIconEx(exePath,0)
            if small and large:
                win32gui.DestroyIcon(small[0])
                hdc = win32ui.CreateDCFromHandle( win32gui.GetDC(0) )
                hbmp = win32ui.CreateBitmap()
                hbmp.CreateCompatibleBitmap( hdc, ico_x, ico_y )
                hdc = hdc.CreateCompatibleDC()
                hdc.SelectObject( hbmp )
                hdc.FillSolidRect( (0,0,ico_x,ico_x), 0xffffff )
                hdc.DrawIcon( (0,0), large[0] )
                iconsDir = getIconsDirectory()
                bmpIconPath = os.path.join(iconsDir,os.path.basename(exePath).split('.')[0]+'.bmp')
                hbmp.SaveBitmapFile( hdc, bmpIconPath)
                iconPath = os.path.join(iconsDir,os.path.basename(exePath).split('.')[0]+'.png')
                makeColorTransparent(Image.open(bmpIconPath), (255, 255, 255)).save(iconPath)
                return iconPath
            else:
                logMessage('WARNING','Filed to generate pixmap from file "%s"'%(exePath))
        else:
            logMessage('WARNING','Filed to generate pixmap from file "%s"'%(exePath))
    except Exception, ex:
        logging.error(ex)
    return ''
    
def getModulePath():
    currPath = getCurrentPath()
    utilsDir = os.path.dirname(currPath)
    #mainDir  = os.path.dirname(utilsDir)
    #logMessage(message='getModulePath: utilsDir = %s' % (utilsDir))
    return utilsDir

def computePath(path):
    if os.path.exists(path):
        return path
    else:
        logging.warning('[computePath] path "%s" does not exist.' % (path))
    return path
#     logMessage('debug', 'path %s' % (path), 'computePath')
#     outPath = ''
#     targetCharachter = '/'
#     elementsList = path.split(targetCharachter)
#     if len(elementsList) == 1:
#         targetCharachter = '\\'
#         elementsList = path.split(targetCharachter)
#     for element in elementsList:
#         if ' ' in element:
#             element = '"%s"'%(element)
#         outPath = outPath+element+targetCharachter
#     #logMessage('debug', 'outPath[:-1] %s' % (outPath[:-1]), 'computePath')
#     return outPath[:-1]

def getIconsDirectory():
    """
        Gets icons directory path 
    """
    moduleDir=os.path.dirname(os.path.realpath(__file__))
    iconsDir=os.path.join(moduleDir,'images')       # Path used by packaged version
    #logging.debug("iconsDirectory: 1st try to read from (%r)." %(iconsDir))
    if not os.path.exists(iconsDir):
        moduleDir=os.path.dirname(moduleDir)
        iconsDir=os.path.join(moduleDir,'images')
        if not os.path.exists(iconsDir):
            moduleDir=os.path.dirname(moduleDir)
            iconsDir=os.path.join(moduleDir,'images')
            if not os.path.exists(iconsDir):
                moduleDir=os.path.dirname(moduleDir)
                iconsDir=os.path.join(moduleDir,'images')
                if not os.path.exists(iconsDir):
                    return 'False'
    #logMessage('debug', 'iconsDir %s' % (iconsDir), 'getIconsDirectory')
    return iconsDir

def getUsefulPath():
    mainDir  = getModulePath()
    dirPath = os.path.join(mainDir,'usefulfiles')
    if not os.path.exists(dirPath):
        os.makedirs(dirPath)
    #logMessage('debug', 'dirPath %s' % (dirPath), 'getUsefulPath')
    return dirPath

def getUsefulPython():
    mainDir  = getModulePath()
    dirPath = os.path.join(mainDir,'usefulRunning')
    if not os.path.exists(dirPath):
        os.makedirs(dirPath)
    #logMessage('debug', 'dirPath %s' % (dirPath), 'getUsefulPath')
    return dirPath

def getCurrentPath():
    """
       Inizialize all the folder needed for the application 
    """  
    modulePath = os.path.dirname(__file__)
    splitLibrary=modulePath.split('library.zip') #This is needed when we use py2exe and the file is zipped in the library.zip
    if len(splitLibrary)>1:
        modulePath=splitLibrary[0]
    #logMessage('debug', 'modulePath %s' % (modulePath), 'getCurrentPath')
    return modulePath
    
def askForm(labelName,buttonName):
    return AskFormEdit(labelName,buttonName)
     
def getDirectoryFileToSaveSystem(parent, dbInst):
    confObjects = dbInst.getRowsTable(constants.TABLE_NAME_CONFIGURATIONS, fields=['config_value'], filtersList=[('config_name', '=', 'SAVE_SCHREENSHOT_EXTENSION')])
    filename = QtGui.QFileDialog.getSaveFileName(None,"Save file", "", str(confObjects[0].config_value))
    logging.info('[getDirectoryFileToSaveSystem] filename: %s' % filename)
    return filename

def getDirectoryFromSystem(parent, pathToOpen=''):
    return QtGui.QFileDialog.getExistingDirectory(parent, "Select Directory", pathToOpen)
    
def getFileFromSystem(desc='Open', startPath='/home/'):
    fileName = QtGui.QFileDialog.getOpenFileName(None, desc, startPath)
    return fileName
    
def getSchreenshotDefaultPath(dbInst):
    for confObj in dbInst.getRowsTable(TABLE_NAME_CONFIGURATIONS, ['config_value'], [('config_name', '=', 'SCHREENSHOT_DB_PATH')]):
        return unicode(confObj.config_value)
    return ''

def getOS():
    platform = sys.platform
    if 'linux' in platform:
        return 'LINUX'
    elif 'win' in platform or 'nt' in os.name:
        return 'WINDOWS'
    else:
        logging.warning('Os not found: %s'%(platform))
        return 'UNKNOWN'

def launchMessage(message='', msgType='message'):
    messBox = QtGui.QMessageBox()
    messBox.setText(unicode(message))
    if msgType == 'message':
        messBox.setStandardButtons(QtGui.QMessageBox.Ok)
    elif msgType == 'question':
        messBox.setStandardButtons(QtGui.QMessageBox.Ok| QtGui.QMessageBox.Cancel)
    if (messBox.exec_() == QtGui.QMessageBox.Ok):
        messBox.accept()
        return True
    else:
        return False
    
def logMessage(msgType='DEBUG', message='', functionName=''):
    msg = '%s[%s] %s: %s'%(unicode(datetime.datetime.now()), functionName, unicode(msgType).upper(), message)
    if msgType.upper() == 'DEBUG':
        logging.debug(msg)
    elif msgType.upper() == 'INFO':
        logging.info(msg)
    elif msgType.upper() == 'WARNING':
        logging.warning(msg)
    elif msgType.upper() == 'ERROR':
        logging.error(msg)
    else:
        logging.debug(msg)

def convertJpgToPng(jpgPath, savePngPath=''):
    if not savePngPath:
        savePngPath = os.path.splitext(jpgPath)[0] + '.png'
    if os.path.exists(jpgPath):
        im = Image.open(jpgPath)
        im.save(savePngPath, 'PNG')
    else:
        logMessage('WARNING', '%s path does not exists' % (jpgPath))
    return savePngPath

def exceptionManagement(ex, message=''):
    traceback.print_exc(file=sys.stdout)
    traceBackMess = traceback.format_exc()
    logging.error(ex)
    logging.error(traceBackMess)
    launchMessage(message + ': %s \n %s'%(ex, traceBackMess))
    
def setTheme(obj):
    for elemObj in obj.__dict__.values():
        setSingleTheme(elemObj)
    obj.setStyleSheet(constants.BACKGROUND_BASE)
    iconsDir = getIconsDirectory()
    mainJpgPath = computePath(os.path.join(iconsDir, ICON_MAIN))
    icon = QtGui.QIcon(mainJpgPath)
    obj.setWindowIcon(icon)

def setSingleTheme(elemObj):
    if isinstance(elemObj, (QtGui.QPushButton, QtGui.QDialogButtonBox)):
        elemObj.setStyleSheet(constants.BACKGROUND_BUTTONS)
        if isinstance(elemObj, QtGui.QPushButton):
            elemObj.setFlat(constants.BUTTONS_FLAT)
    elif isinstance(elemObj, QtGui.QTabWidget):
        elemObj.setStyleSheet(constants.BACKGROUND_TABWIDGET)
    elif isinstance(elemObj, (QtGui.QTextEdit, QtGui.QTextBlock, QtGui.QTreeView, QtGui.QLineEdit, QtGui.QTableView, QtGui.QTableWidget, QtGui.QListView, QtGui.QListWidget, QtGui.QComboBox, QtGui.QSpinBox, QtGui.QDoubleSpinBox)):
        elemObj.setStyleSheet(constants.BACKGROUND_TABLES)
    elif isinstance(elemObj, (QtGui.QMenuBar, QtGui.QStatusBar)):
        elemObj.setStyleSheet(constants.BACKGROUND_MENU_BAR)
    elif isinstance(elemObj, QtGui.QMenu):
        elemObj.setStyleSheet(constants.BACKGROUND_MENU)


if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    aaa = getPythonPathExe()
    print aaa
    app.exec_()
